package walkera.cn.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


import java.util.Iterator;
import java.util.LinkedList;

import walkera.cn.bean.Cell;
import walkera.cn.bean.Square;


public class GameView extends SurfaceView    {

    public interface GameListener {
        void onGameState(int score ,boolean isOver);
    }

    private boolean runing;
    private Paint paint;

    private Paint paintBackgrond ;

    /**列*/
    private int COLUMNS = 12;
    /**行*/
    private int ROWS = 18;
    /**每一格的宽度*/
    private int cellWidth;
    private LinkedList<Cell> cellsList;
    private Square currentSquare;
    private int[] limit = new int[ROWS];
    private boolean quikDown;
    private int score;
    private GameListener gameListener;

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public void setGameListener(GameListener gameListener) {
        this.gameListener = gameListener;
    }



    private void init() {
        getHolder().addCallback(callback);
        cellsList = new LinkedList<>();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintBackgrond = new Paint(Paint.ANTI_ALIAS_FLAG);
    }




    private void initCell() {
        cellWidth = getWidth() / COLUMNS;
        currentSquare = Square.generate(COLUMNS);
    }


    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            runing = true;
            initCell();
            Thread thread = new Thread(runnable);
            thread.start();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            runing = false;
        }
    };


    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (runing) {
                draw();
                boolean noWait = false;

                if (!currentSquare.canMoveDown(cellsList, ROWS)) {
                    fillCells();
                    refreshLimit();
                    if (hasFadeRow() != -1) {
                        noWait = true;
                    } else {
                        for (int i = 0; i < 4; i++) {
                            cellsList.removeLast();
                        }
                    }
                }

                try {
                    if (quikDown || noWait) {
                        Thread.sleep(50);
                    } else {
                        Thread.sleep(200);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                control(noWait);
            }
        }
    };



    public synchronized void rotate() {
        if (currentSquare != null && runing) {
            int[][] ints = currentSquare.canRotate(90, cellsList, COLUMNS, ROWS);
            if (ints != null) {
                currentSquare.rotate(  ints);
                draw(); //rotate
            }
        }
    }


    public synchronized void moveLeft() {
        if (currentSquare != null && currentSquare.canMoveLeft(cellsList) && runing) {
            currentSquare.moveLeft();
            draw();//  moveLeft
        }
    }

    public synchronized void moveRight() {
        if (currentSquare != null && currentSquare.canMoveRight(cellsList, COLUMNS) && runing) {
            currentSquare.moveRight();
            draw(); //moveRight
        }
    }


    public void setQuikDown(boolean quikDown) {
        this.quikDown = quikDown;
    }


    private void fade() {
        int count = 0;
        //检测可消除的单元方块
        int fadeRow = 0;
        while ((fadeRow = hasFadeRow()) != -1) {
            //删除单元格
            count++;
            //explode(fadeRow);//抖动效果
            //explode2(fadeRow);//爆炸效果
            deleteRowCell(fadeRow);
            moveAllCell(fadeRow);
            draw();
            refreshLimit();
        }
        caculateScore(count);
    }

    /**
     * 计算分数
     */
    private void caculateScore(int count) {
        if (count > 0) {
            score += Math.pow(count, 2);
            if (gameListener != null) {
                gameListener.onGameState(score * 100 ,false);
            }
        }

    }

    /**
     * 是否有可消除的行
     * @return 可消除的行号 ， -1 表示没有符合可以消除的
     */
    private int hasFadeRow() {
        for (int i = limit.length - 1; i >= 0; i--) {
            if (limit[i] == COLUMNS) {
                limit[i] = 0;
                return i;
            }
        }
        return -1;
    }

    /**
     * 刷新行限制检测
     */
    private void refreshLimit() {
        // 重置为0
        for (int i = 0; i < limit.length; i++) {
            limit[i] = 0;
        }

        for (int i = 0; i < cellsList.size(); i++) {
            Cell cell = cellsList.get(i);
            if (cell.getRow() > -1){
                limit[cell.getRow()]++;
            }

        }
    }

    //删除某一行的单元格
    private void deleteRowCell(int row) {
        Iterator<Cell> iterator = cellsList.iterator();
        while (iterator.hasNext()) {
            Cell next = iterator.next();
            if (next.getRow() == row) {
                iterator.remove();
            }
        }
    }

    //移动单元格 填补空行
    private void moveAllCell(int row) {
        for (int i = 0; i < cellsList.size(); i++) {
            Cell cell = cellsList.get(i);
            if (cell.getRow() < row)
                cell.setRow(cell.getRow() + 1);
        }
    }




    private synchronized void draw( ) {
        Canvas canvas = getHolder().lockCanvas();
        canvas.drawColor(Color.parseColor("#9ead86"));



        //
        paintBackgrond.setColor(Color.parseColor("#879372"));
        paintBackgrond.setStyle(Paint.Style.FILL);
        paintBackgrond.setStrokeWidth(3);
        int padding = 5;


        for (int i = 0; i < ROWS ; i++) {
            for (int j = 0; j < COLUMNS ; j++) {
            int left =  j * cellWidth + padding  ;
            int right = left + cellWidth -2*padding ;

            int top = i * cellWidth  +padding ;
            int bottom = top + cellWidth -2*padding ;
            canvas.drawRoundRect( left , top , right ,  bottom  ,0, 0, paintBackgrond);

            }
        }


        paintBackgrond.setColor(Color.parseColor("#9ead86"));
        paintBackgrond.setStyle(Paint.Style.STROKE);
        paintBackgrond.setStrokeWidth(5);
        int padding2 = 15;
        for (int i = 0; i < ROWS ; i++) {
            for (int j = 0; j < COLUMNS ; j++) {
                int left =  j * cellWidth + padding2  ;
                int right = left + cellWidth -2*padding2 ;

                int top = i * cellWidth  +padding2 ;
                int bottom = top + cellWidth -2*padding2 ;

                canvas.drawRoundRect( left , top , right ,  bottom  ,0, 0, paintBackgrond);
            }
        }


        // 绘制正在下落的方块
        if (currentSquare != null){
            for (int i = 0; i < currentSquare.cells.length; i++) {
                int[] cell = currentSquare.cells[i];
                drawCell(canvas,  cell[0], cell[1], currentSquare.color );
            }
        }

        for (int i = 0; i < cellsList.size(); i++) {
             Cell cell = cellsList.get(i);
            drawCell(canvas, cell.getRow(), cell.getCol(), cell.getColor() );
        }
        getHolder().unlockCanvasAndPost(canvas);
    }


    /**
     * 将掉落的那个方块填充到 下面的格子中
     */
    private void fillCells() {
        for (int i = 0; i < currentSquare.cells.length; i++) {
            Cell cell =  new Cell(currentSquare.cells[i][0], currentSquare.cells[i][1], currentSquare.color);
            cellsList.add(cell);
        }
    }

    /**
     * 下移控制
     */
    private synchronized void control(boolean noWait) {
        if (currentSquare.canMoveDown(cellsList, ROWS)) {
            currentSquare.move();
        } else {
            if (!noWait){
                fillCells();
            }

            refreshLimit();
            currentSquare = null;
            quikDown = false;
            fade();
            //生成新的可运动方块
            currentSquare = Square.generate(COLUMNS);
            draw();
            if (!currentSquare.canMoveDown(cellsList, ROWS)) {
                runing = false;
                post(new Runnable() {
                    @Override
                    public void run() {
                        if (gameListener != null) {
                            gameListener.onGameState(score * 100 ,true);
                        }
                    }
                });
            }
        }
    }


    /**
     * 绘制一个小格子
     */

    private void drawCell(Canvas canvas, int row, int col, int color ) {
        int radius = 1;
        //小格子
        paint.setColor(Color.parseColor("#000000"));
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRoundRect(col * cellWidth   , row * cellWidth   , col * cellWidth + cellWidth   , row * cellWidth + cellWidth    , radius, radius, paint);
        //给小格子描边
        paint.setColor(Color.parseColor("#9ead86"));
        paint.setStrokeWidth(6);
        paint.setStyle(Paint.Style.STROKE);
        int padding = 15 ;
        canvas.drawRoundRect(
                col * cellWidth + padding ,

                row * cellWidth +  padding ,

                col * cellWidth + cellWidth - padding ,

                row * cellWidth + cellWidth  -padding ,
                radius, radius, paint);

        paint.setColor(Color.parseColor("#9ead86"));
        paint.setStrokeWidth(10);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawRoundRect(col * cellWidth  , row * cellWidth  , col * cellWidth + cellWidth  , row * cellWidth + cellWidth  , radius, radius, paint);
    }




    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        cellWidth = getMeasuredWidth() / COLUMNS;
        int height = ROWS * cellWidth; // 最终游戏界面的高度
        setMeasuredDimension(getMeasuredWidth(), height );
    }

}
